
exports.__esModule = true;
exports.default = void 0;

const _utils = require('../utils');

const _vnodes = require('../utils/vnodes');

const _createNamespace = (0, _utils.createNamespace)('form');
const createComponent = _createNamespace[0];
const bem = _createNamespace[1];

const _default = createComponent({
  props: {
    colon: Boolean,
    labelWidth: [Number, String],
    labelAlign: String,
    inputAlign: String,
    scrollToError: Boolean,
    validateFirst: Boolean,
    errorMessageAlign: String,
    validateTrigger: {
      type: String,
      default: 'onBlur',
    },
    showError: {
      type: Boolean,
      default: true,
    },
    showErrorMessage: {
      type: Boolean,
      default: true,
    },
  },
  provide: function provide() {
    return {
      vanForm: this,
    };
  },
  data: function data() {
    return {
      fields: [],
    };
  },
  methods: {
    validateSeq: function validateSeq() {
      const _this = this;

      return new Promise(((resolve, reject) => {
        const errors = [];

        _this.fields.reduce((promise, field) => promise.then(() => {
          if (!errors.length) {
            return field.validate().then((error) => {
              if (error) {
                errors.push(error);
              }
            });
          }
        }), Promise.resolve()).then(() => {
          if (errors.length) {
            reject(errors);
          } else {
            resolve();
          }
        });
      }));
    },
    validateAll: function validateAll() {
      const _this2 = this;

      return new Promise(((resolve, reject) => {
        Promise.all(_this2.fields.map((item) => item.validate())).then((errors) => {
          errors = errors.filter((item) => item);

          if (errors.length) {
            reject(errors);
          } else {
            resolve();
          }
        });
      }));
    },
    // @exposed-api
    validate: function validate(name) {
      if (name) {
        return this.validateField(name);
      }

      return this.validateFirst ? this.validateSeq() : this.validateAll();
    },
    validateField: function validateField(name) {
      const matched = this.fields.filter((item) => item.name === name);

      if (matched.length) {
        return new Promise(((resolve, reject) => {
          matched[0].validate().then((error) => {
            if (error) {
              reject(error);
            } else {
              resolve();
            }
          });
        }));
      }

      return Promise.reject();
    },
    // @exposed-api
    resetValidation: function resetValidation(name) {
      this.fields.forEach((item) => {
        if (!name || item.name === name) {
          item.resetValidation();
        }
      });
    },
    // @exposed-api
    scrollToField: function scrollToField(name) {
      this.fields.forEach((item) => {
        if (item.name === name) {
          item.$el.scrollIntoView();
        }
      });
    },
    addField: function addField(field) {
      this.fields.push(field);
      (0, _vnodes.sortChildren)(this.fields, this);
    },
    removeField: function removeField(field) {
      this.fields = this.fields.filter((item) => item !== field);
    },
    getValues: function getValues() {
      return this.fields.reduce((form, field) => {
        form[field.name] = field.formValue;
        return form;
      }, {});
    },
    onSubmit: function onSubmit(event) {
      event.preventDefault();
      this.submit();
    },
    // @exposed-api
    submit: function submit() {
      const _this3 = this;

      const values = this.getValues();
      this.validate().then(() => {
        _this3.$emit('submit', values);
      }).catch((errors) => {
        _this3.$emit('failed', {
          values,
          errors,
        });

        if (_this3.scrollToError) {
          _this3.scrollToField(errors[0].name);
        }
      });
    },
  },
  render: function render() {
    const h = arguments[0];
    return h('form', {
      class: bem(),
      on: {
        submit: this.onSubmit,
      },
    }, [this.slots()]);
  },
});

exports.default = _default;
